package test.groovy

import com.sun.javafx.scene.control.skin.VirtualFlow
import com.sun.prism.shader.Solid_TextureYV12_AlphaTest_Loader
import com.thaiopensource.xml.dtd.om.Def
import groovy.transform.AutoExternalize
import groovy.transform.Canonical
import groovy.transform.EqualsAndHashCode
import groovy.transform.Immutable
import groovy.transform.IndexedProperty
import groovy.transform.Memoized
import groovy.transform.Sortable
import groovy.transform.ToString
import groovy.transform.TupleConstructor
import groovy.transform.builder.Builder
import groovy.transform.builder.SimpleStrategy
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.SimpleType
import groovy.xml.MarkupBuilder
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.runtime.IOGroovyMethods
import org.w3c.dom.Node

import java.util.regex.Matcher

/*def a=5 as String
def  b=3.5g as BigDecimal *//*3.5g 正确 3.5a 随便写个字母还是不认的*//*
def  c=3.5g as BigInteger *//*3.5g 正确 3.5a 随便写个字母还是不认的*//*
println a
println b*/

/*def range = 5..10; //5-10 都包括/
def range2 = 5..<10; //5-9/
//def range3 = 5..>10; //5-9 无错的/
println range  //类型是groovy.lang.IntRange
println range2
for (x in range) {
    println x
}
for (def dd : range) {
    println dd
}*/

/*
println new File("E:/aaa.txt").getText()
new File("E:/aaa.txt").eachLine() {
        println it //只有一个参数时 it即参数
}
new File("E:/aaa.txt").eachLine(30) {
    str,line->
        println "${line} === ${str}"
}
new File("E:/aaa.txt").write("fdsafsdf")
*/

/*def f(a) {
    println a //it第一个参数
}
f()
f(1)
def f2(map,a){
    println map
    println a
}
f2(name:"1",age:"32",10)
//f2(name:"1",age:"32",10,5) //会报错找不到方法*/

/*def b
println 3 > 2 ? 1 : 0
String a = "HelloWorld";
println(a.center(18, "=")); //大于长度两头补齐
println a.center(2) //小于长度直接返回
String s = "a12fasdf4546a56";
s.eachMatch("\\d*") {
    ch -> println ch.class
}*/

/*
def a = 1..3 as Range
def b = '1'..'z'
b1=b.minus('A')
println a
println b
println b1
println b1.dump()
*/
/*
def matcher = 'Groovy' =~ 'Groovy'
println matcher.matches()
println 'Groovy' =~ 'oo'
println 'Groovy' ==~ 'Groovy'
println 'Groovy' ==~ 'oo'
println 'Groovy' =~ '∧G'
println 'Groovy' =~ 'G$'
println 'Groovy' =~ 'Gro*vy'
println 'Groovy' =~ 'Gro{2}vy'*/

/*
trait Marks {
    void DisplayMarks() {
        println("Display Marks");
    }
}

trait Marks2 { //具有默认方法和属性的接口
    void DisplayMarks2() {
        println("Display Marks2");
    }
}

class Student implements Marks, Marks2 {
    int StudentID
    int Marks1;
}

Student st = new Student();
st.StudentID = 1;
st.Marks1 = 10;
st.DisplayMarks();
st.DisplayMarks2();*/

def clos = { println "Hello World" } as Closure;
clos.call();
clos()

def lst = [1, 2, 3, 4];
def value;
value = lst.find { element -> element > 2 }
println(value);
value2 = lst.findAll { element -> element > 2 }
println(value2);
value3 = lst.any { element -> element > 2 }
println(value3); //true
value4 = lst.any { element -> element > 4 }
println(value4); //false
value5 = lst.every() { element ->
    element > 0
}
println(value5); //true
value6 = lst.every { element ->
    element > 4 //返回值
}
println(value6); //false

newlst = lst.collect {element -> return element * element}
println(newlst);

/*
StringWriter stringWriter = new StringWriter();
def mB = new MarkupBuilder(stringWriter) //参数 内容输出的位置 无控制台

// Compose the builder
mB.collection(shelf: 'New Arrivals', ss: "ss") {
    movie(title: 'Enemy Behind')
    type('War, Thriller', aa: "aa", bb: "bb")
    format('DVD')
    year('2003')
    rating('PG')
    aa('PG')
    stars(10)
    description('Talk about a US-Japan war')
}
def string = stringWriter.toString()
println string
//<collection shelf='New Arrivals' ss='ss'>
//<movie title='Enemy Behind' />
//<type aa='aa' bb='bb'>War, Thriller</type>
//  <format>DVD</format>
//<year>2003</year>
//  <rating>PG</rating>
//<aa>PG</aa>
//  <stars>10</stars>
//<description>Talk about a US-Japan war</description>
//</collection>
//println str.class
println "--------------"*/

/*class Example {
    //xml解析
    static void main(String[] args) {
        String str = '''<collection shelf='New Arrivals' ss='ss'>
  <movie title='Enemy Behind' />
  <type aa='aa' bb='bb'>War, Thriller</type>
  <format>DVD</format>
  <year>2003</year>
  <rating>PG</rating>
  <aa>PG</aa>
  <stars>10</stars>
  <description>Talk about a US-Japan war</description>
</collection>'''
        def parser = new XmlParser()
        def doc = parser.parseText(str);  //doc是collection节点
        def object = doc.type[0]
        println object['@aa']
        println object['@bb']
        println object.text()
    }
}*/

/*
def mp = [1: ['Enemy Behind', 'War, Thriller', 'DVD', '2003',
              'PG', '10', 'Talk about a US-Japan war'],
          2: ['Transformers', 'Anime, Science Fiction', 'DVD', '1989',
              'R', '8', 'A scientific fiction'],
          3: ['Trigun', 'Anime, Action', 'DVD', '1986',
              'PG', '10', 'Vash the Stam pede'],
          4: ['Ishtar', 'Comedy', 'VHS', '1987', 'PG',
              '2', 'Viewable boredom ']]
println mp.getClass()
mp.each { println it.value.class}*/

/*
class EmailDsl {
    String toText
    String fromText
    String body


    def static make(closure) {
        EmailDsl emailDsl = new EmailDsl()
        // any method called in closure will be delegated to the EmailDsl class
        closure.delegate = emailDsl
        closure()
    }

    def to(String toText) {
        this.toText = toText
    }

    def from(String fromText) {
        this.fromText = fromText
    }

    def body(String bodyText) {
        this.body = bodyText
    }
    def log(){
        println this.toText
        println(this.fromText)
        println this.body
    }
}

EmailDsl.make {
    to "Nirav Assar"
    from "Barack Obama"
    body "How are things? We are doing well. Take care"
    log()
}
*/

/*
def nodeBuilder = new NodeBuilder()

def studentlist = nodeBuilder.userlist {
    user(id: '1', studentname: 'John', Subject: 'Chemistry')
    user(id: '2', studentname: 'Joe', Subject: 'Maths')
    user(id: '3', studentname: 'Mark', Subject: 'Physics')
}

println(studentlist)

def builder = new groovy.json.JsonBuilder()
builder([1, 2, 3])
println(builder.toString());
builder.call([3.4, 5])
println builder.toString()

class dom {
    static void main(String[] str) {
        String records = '''
   <library>
	
      <Student>
         <StudentName division = 'A'>Joe</StudentName>
         <StudentID>1</StudentID>
      </Student>
	  
      <Student>
         <StudentName division = 'B'>John</StudentName>
         <StudentID>2</StudentID>
      </Student>
	  
      <Student>
         <StudentName division = 'C'>Mark</StudentName>
         <StudentID>3</StudentID>
      </Student>
		
   </library>'''


        def rd = new StringReader(records)
        def doc = groovy.xml.DOMBuilder.parse(rd)
        println doc.getElementsByTagName("Student").getLength()
        def student = doc.getElementsByTagName("Student")
        println student
        println student.item(0).getChildNodes()
    }
}


def text = '''This Tutorial is <% out.print TutorialName %> The Topic name is ${TopicName}'''
def template = new groovy.text.StreamingTemplateEngine().createTemplate(text)

def binding = [TutorialName : "Groovy", TopicName  : "Templates"]
String response = template.make(binding)
println(response)
*/

/*class Student {
    protected dynamicProps = [:]
    def name;
    void setProperty(String pName, val) {
        dynamicProps[pName] = val
        println "setProperty ${pName} ${val}"
    }

    def getProperty(String pName) {
        dynamicProps[pName]
    }

    def invokeMethod(String name, Object args) {
        return "called invokeMethod $name $args"
    }

    def methodMissing(String name, def args) {
        println "Missing method"
    }

    def propertyMissing(String var2) {
        return "aa"
    }

    def display() {
        println metaClass
        println getMetaClass()
        println dynamicProps
    }
}
class OwnMetaClassImplementation implements MetaClass{

    @Override
    Object invokeMethod(Class aClass, Object o, String s, Object[] objects, boolean b, boolean b1) {
        return null
    }

    @Override
    Object getProperty(Class aClass, Object o, String s, boolean b, boolean b1) {
        return null
    }

    @Override
    void setProperty(Class aClass, Object o, String s, Object o1, boolean b, boolean b1) {

    }

    @Override
    Object invokeMissingMethod(Object o, String s, Object[] objects) {
        return null
    }

    @Override
    Object invokeMissingProperty(Object o, String s, Object o1, boolean b) {
        return null
    }

    @Override
    Object getAttribute(Class aClass, Object o, String s, boolean b) {
        return null
    }

    @Override
    void setAttribute(Class aClass, Object o, String s, Object o1, boolean b, boolean b1) {

    }

    @Override
    void initialize() {

    }

    @Override
    List<MetaProperty> getProperties() {
        return null
    }

    @Override
    List<MetaMethod> getMethods() {
        return null
    }

    @Override
    List<MetaMethod> respondsTo(Object o, String s, Object[] objects) {
        return null
    }

    @Override
    List<MetaMethod> respondsTo(Object o, String s) {
        return null
    }

    @Override
    MetaProperty hasProperty(Object o, String s) {
        return null
    }

    @Override
    MetaProperty getMetaProperty(String s) {
        return null
    }

    @Override
    MetaMethod getStaticMetaMethod(String s, Object[] objects) {
        return null
    }

    @Override
    MetaMethod getMetaMethod(String s, Object[] objects) {
        return null
    }

    @Override
    Class getTheClass() {
        return null
    }

    @Override
    Object invokeConstructor(Object[] objects) {
        return null
    }

    @Override
    Object invokeMethod(Object o, String s, Object[] objects) {
        return null
    }

    @Override
    Object invokeMethod(Object o, String s, Object o1) {
        return null
    }

    @Override
    Object invokeStaticMethod(Object o, String s, Object[] objects) {
        return null
    }

    @Override
    Object getProperty(Object o, String s) {
        return null
    }

    @Override
    void setProperty(Object o, String s, Object o1) {

    }

    @Override
    Object getAttribute(Object o, String s) {
        return null
    }

    @Override
    void setAttribute(Object o, String s, Object o1) {

    }

    @Override
    ClassNode getClassNode() {
        return null
    }

    @Override
    List<MetaMethod> getMetaMethods() {
        return null
    }

    @Override
    int selectConstructorAndTransformArguments(int i, Object[] objects) {
        return 0
    }

    @Override
    MetaMethod pickMethod(String s, Class[] classes) {
        return null
    }
}
Student mst = new Student();
println mst instanceof GroovyObject;
println mst instanceof GroovyObjectSupport;
mst.metaClass=new OwnMetaClassImplementation();
mst.Name = "Joe";
mst.ID = 1;

println(mst.Name);
println(mst.ID);
mst.display()
mst.getMetaClass().setAttribute(mst, "name","AA")
mst.getMetaClass().getAttribute(mst, "name")
println(mst.name);
println(mst.getName());
println(mst.Name);*/

/*class SomeGroovyClass {

    def field1 = 'ha'
    def field2 = 'ho'

    def getField1() {
        return 'getHa'
    }
}

def someGroovyClass = new SomeGroovyClass()

println someGroovyClass.field1
println someGroovyClass.metaClass.getAttribute(someGroovyClass, 'field1') == 'ha'
println someGroovyClass.metaClass.getAttribute(someGroovyClass, 'field2') == 'ho'
*/

/*
class SomeGroovyClass {

    def property1 = 'ha'
    def field2 = 'ho'
    def field4 = 'hu'

    def getField1() {
        return 'getHa'
    }

    def getProperty(String name) {
        if (name != 'field3')
            return metaClass.getProperty(this, name)     // 1⃣️
        else
            return 'field3'
    }
}

def someGroovyClass = new SomeGroovyClass()

println someGroovyClass.field1 == 'getHa'
println someGroovyClass.field2 == 'ho'
println someGroovyClass.field3 == 'field3'
println someGroovyClass.field4 == 'hu'*/

/*println "aa" == "aa"
def aa = "aa";
println aa.is("aa")
println "aa".equals("aa")*/

/*
@ToString
class Base {
    String occupation

    Base() {}

    Base(String job) { occupation = job?.toLowerCase() }
}


@ToString(includeSuper = true)
@EqualsAndHashCode
@TupleConstructor(includeSuperProperties = true, callSuper = true)
//@Canonical //ToString  EqualsAndHashCode  TupleConstructor 三者的组合
class Person extends Base {
    String firstName
    @Lazy String lastName
    @IndexedProperty List someList = []
    private String name;

}

println new Person(firstName: "aa", lastName: "bb")
def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
def p2 = new Person(firstName: 'Jack', lastName: 'Nicholson')
def p3 = new Person()
def p4 = new Person(firstName: 'Jack')
def p5 = new Person('Jack', "Nicholson")
println p3
println p4
println p5
println p1 == p2
println p1.hashCode() == p2.hashCode()
println "----------"
def p11 = new Person(firstName: 'Jack', lastName: 'Nicholson')
def p21 = new Person('ACTOR', 'Jack', 'Nicholson')
println p11.firstName == p21.firstName
println p11.lastName == p21.lastName
println p11.toString()
println p21.toString()
p11.setSomeList(new ArrayList())
p11.setSomeList(0, 'value') //下标索引的方法 输值 取值
p11.setSomeList(3, 123)

println p11.someList[0] == 'value'
println p11.someList*/

class TripleCategory {
    public static Integer triple(Integer self) {
        3 * self
    }
}

@Category(Integer)
class TripleCategory2 {
    //参数Integer self不用写了
    public Integer triple() { 3 * this }
}

println "TripleCategory==TripleCategory.class ${TripleCategory==TripleCategory.class}"
use(TripleCategory) {
    println 9 == 3.triple()
}
use(TripleCategory2) {
    println 9 == 3.triple()
}

/*
@Canonical
@Sortable
@Builder(builderStrategy=SimpleStrategy)
class Person {
    String first
    String last
    Integer born
}

def people = [
        new Person(first: 'Johnny', last: 'Depp', born: 1963),
        new Person(first: 'Keira', last: 'Knightley', born: 1985),
        new Person(first: 'Geoffrey', last: 'Rush', born: 1951),
        new Person(first: 'Orlando', last: 'Bloom', born: 1977)
]
def p1 = new Person().setFirst('Johnny').setLast('Depp').setBorn(1963)
println people[0] > people[2]
people.sort(true)
println people
println people.sort()*.last == ['Rush', 'Depp', 'Knightley', 'Bloom']
println people.sort(false, Person.comparatorByFirst())*.first == ['Geoffrey', 'Johnny', 'Keira', 'Orlando']
println people.sort(false, Person.comparatorByLast())*.last == ['Bloom', 'Depp', 'Knightley', 'Rush']
println people.sort(false, Person.comparatorByBorn())*.last == ['Rush', 'Depp', 'Bloom', 'Knightley']


@Immutable
class Point {
    int x
    int y
}
@Immutable(knownImmutables=['b','c'])
class Triangle {
    Point a,b,c
}*/

@Memoized
long longComputation(int seed) {
    // 延缓计算
    Thread.sleep(1000 * seed)
    System.nanoTime()
}

def x = longComputation(1) // 1 秒后返回结果
println x
def y = longComputation(1) // 立刻返回结果
println y
def z = longComputation(2) // 2 秒后返回结果
println z
def z1 = longComputation(2) // 已缓存结果了
println z1

